﻿//   **************************************************************************
//   *                                                                        *
//   *  This program is free software: you can redistribute it and/or modify  *
//   *  it under the terms of the GNU General Public License as published by  *
//   *  the Free Software Foundation, either version 3 of the License, or     *
//   *  (at your option) any later version.                                   *
//   *                                                                        *
//   *  This program is distributed in the hope that it will be useful,       *
//   *  but WITHOUT ANY WARRANTY; without even the implied warranty of        *
//   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
//   *  GNU General Public License for more details.                          *
//   *                                                                        *
//   *  You should have received a copy of the GNU General Public License     *
//   *  along with this program.  If not, see <http://www.gnu.org/licenses/>. *
//   *                                                                        *
//   **************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace U413.Domain.Utilities
{
    /// <summary>
    /// Utility used to generate alpha-numeric short codes representing 64-bit integer IDs.
    /// </summary>
    public static class ShortCodes
    {
        /// <summary>
        /// The random object to randomize the character selection.
        /// </summary>
        private static Random rand = new Random();

        /// <summary>
        /// You may change the "shortcode_Keyspace" variable to contain as many or as few characters as you
        /// please.  The more characters that aer included in the "shortcode_Keyspace" constant, the shorter
        /// the codes you can produce for a given long.
        /// </summary>
        const string shortcode_Keyspace = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789";

        /// <summary>
        /// Arbitrary constant for the maximum length of ShortCodes generated by the application.
        /// </summary>
        const int shortcode_maxLen = 12;

        /// <summary>
        /// Converts a 64-bit integer to a string short code.
        /// </summary>
        /// <param name="number">The value to be converted.</param>
        /// <returns>A string short code.</returns>
        public static string LongToShortCode(long number)
        {
            int ks_len = shortcode_Keyspace.Length;
            string sc_result = "";
            long num_to_encode = number;
            long i = 0;
            do
            {
                i++;
                sc_result = shortcode_Keyspace[(int)(num_to_encode % ks_len)] + sc_result;
                num_to_encode = ((num_to_encode - (num_to_encode % ks_len)) / ks_len);
            }
            while (num_to_encode != 0);
            return sc_result;
        }

        /// <summary>
        /// Converts a string short code to a 64-bit integer.
        /// </summary>
        /// <param name="shortcode">The string short code to be converted.</param>
        /// <returns>A 64-bit integer.</returns>
        public static long ShortCodeToLong(string shortcode)
        {
            int ks_len = shortcode_Keyspace.Length;
            long sc_result = 0;
            int sc_length = shortcode.Length;
            string code_to_decode = shortcode;
            for (int i = 0; i < code_to_decode.Length; i++)
            {
                sc_length--;
                char code_char = code_to_decode[i];
                sc_result += shortcode_Keyspace.IndexOf(code_char) * (long)(Math.Pow((double)ks_len, (double)sc_length));
            }
            return sc_result;
        }
    }
}
